package com.me.study.async;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

/**
 * spring 异步调用--@Aysnc：
 *
 * @author ME
 * @date   2019/12/25
 */
@Configurable
@EnableAsync// 开启异步任务功能
public class AsyncConfig implements AsyncConfigurer {

	@Bean("asyncPool1")
	@Override
	public Executor getAsyncExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		// 这一步千万不能忘了，否则报错： java.lang.IllegalStateException: ThreadPoolTaskExecutor not initialized
		// 而且最好放在最上面  否则下面 setter() 对 Executor都不会生效
		executor.initialize();

		//核心线程数
		executor.setCorePoolSize(2);
		// 最大线程数
		executor.setMaxPoolSize(5);
		//队列大小
		executor.setQueueCapacity(20);
		//线程最大空闲时间
		executor.setKeepAliveSeconds(300);
		//指定用于新创建的线程名称的前缀。
		executor.setThreadNamePrefix("my-async-");
		// 拒绝策略（一共四种，此处省略）
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		return executor;
	}

	@Bean("asyncPool2")
	public Executor getAsyncExecutor2() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		// 这一步千万不能忘了，否则报错： java.lang.IllegalStateException: ThreadPoolTaskExecutor not initialized
		// 而且最好放在最上面  否则下面 setter() 对 Executor都不会生效
		executor.initialize();

		executor.setCorePoolSize(2);
		executor.setMaxPoolSize(5);
		executor.setQueueCapacity(10);
		//线程最大空闲时间
		executor.setKeepAliveSeconds(300);
		//指定用于新创建的线程名称的前缀。
		executor.setThreadNamePrefix("my-async-pool2-");
		executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
		return executor;
	}

	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return new SimpleAsyncUncaughtExceptionHandler();
	}
}
